#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <openssl/evp.h>

int sm4_cbc_decrypt(const unsigned char *key, const unsigned char *iv,
                    const unsigned char *in, size_t in_len,
                    unsigned char *out, size_t *out_len) {
    EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
    if (!ctx) return -1;

    if (EVP_DecryptInit_ex(ctx, EVP_sm4_cbc(), NULL, key, iv) != 1 ||
        EVP_DecryptUpdate(ctx, out, (int*)out_len, in, in_len) != 1) {
        EVP_CIPHER_CTX_free(ctx); return -1;
    }

    int tmplen;
    EVP_DecryptFinal_ex(ctx, out + *out_len, &tmplen);
    *out_len += tmplen;
    EVP_CIPHER_CTX_free(ctx);
    return 0;
}

int main() {
    unsigned char key[16] = {
        0x51,0x00,0xa4,0x6f,0xbb,0x9a,0x72,0x69,
        0xaa,0x83,0x17,0x3c,0x1e,0xbf,0xe5,0x5d
    };
    unsigned char iv[16] = {
        0xf8,0x8b,0x7a,0xcf,0x32,0xe2,0x5e,0xc9,
        0x61,0xe1,0x11,0xa8,0x18,0x6a,0x5d,0xd9
    };

    // 读取密文
    FILE *fp = fopen("sm4.cipher", "rb");
    if (!fp) { fprintf(stderr, "Ciphertext file not found. Run sm4_encrypt first.\n"); return 1; }
    fseek(fp, 0, SEEK_END);
    size_t cipher_len = ftell(fp);
    rewind(fp);
    unsigned char *ciphertext = malloc(cipher_len);
    fread(ciphertext, 1, cipher_len, fp);
    fclose(fp);

    unsigned char plaintext[256];
    size_t plain_len = sizeof(plaintext);

    if (sm4_cbc_decrypt(key, iv, ciphertext, cipher_len, plaintext, &plain_len) == 0) {
        plaintext[plain_len] = '\0';
        printf("SM4 decrypt result: %s\n", plaintext);
    } else {
        fprintf(stderr, "SM4 decrypt failed\n");
        free(ciphertext);
        return 1;
    }

    free(ciphertext);
    return 0;
}
